import { ACCESS_TOKEN, REFRESH_TOKEN, RefreshTokenInvalid } from "@/global/constants"
import {
  getRefreshToken,
  removeAccessToken,
  removeRefreshToken,
  setAccessToken,
  setRefreshToken
} from "./cacheToken"
import SYRequest from "../request"
import { BASE_URL, TIME_OUT } from "../config"
import { localCache } from "@/utils/cacheData"
import syRequest from ".."
import router from "../../router/index" // 确保路径正确

// h后续的请求数组
let expiredRequestArr: any[] = []

/**
 * 添加当前存储的由于过期导致失败的请求
 */
export const addExpiredRequest = (config: any) => {
  expiredRequestArr.push(() => {
    syRequest.instance(config)
  })
}

/**
 * 执行当前存储的由于过期导致失败的请求
 */
export const retryRequest = () => {
  console.log("重新请求上次中断的数据")
  expiredRequestArr.forEach((request) => request())
  expiredRequestArr = []
}

/* 实例化axios */
const refreshTokenRequest = new SYRequest({
  baseURL: BASE_URL,
  timeout: TIME_OUT,
  interceptors: {
    requestSuccessFn: (config) => {
      /* 携带长token发起请求 */
      if (config.headers && getRefreshToken()) {
        config.headers[REFRESH_TOKEN] = getRefreshToken()
      }
      return config
    }
  }
})

// 防抖标识，保证一次只能请求一次短token，防止客户多此操作，多次请求
export let flag = false

/* 
    短token过期，携带token去重新请求token 
    获取到新的长短token存入storage中
    在刷新短token的时候回也返回新的长token，延续长token，
    这样活跃用户在持续操作过程中不会被迫退出登录。长时间无操作的非活
    跃用户长token过期重新登录
*/
export function refreshTokenServer(id, account) {
  if (flag) return
  flag = true
  return refreshTokenRequest.get({
    url: "/authority/refresh",
    params: {
      id,
      account
    },
    interceptors: {
      responseSuccessFn(res) {
        // 获取到配置和后端响应的数据
        // console.log(res.headers)
        const rtInvalid = res.headers[RefreshTokenInvalid]

        /* 长token失效 --> 退出登录 */
        if (rtInvalid) {
          console.log("rtInvalid 长token失效")
          localCache.clearCache()
          /**
           * 此时 refreshToken 也已经失效了
           * 返回登录页，让用户重新进行登录操作
           */

          router.push("/login")
        }

        if (res.data.code == 200) {
          // console.log(res.headers)

          const accessToken = res.headers[ACCESS_TOKEN]
          const refreshToken = res.headers[REFRESH_TOKEN]

          setAccessToken(accessToken)
          setRefreshToken(refreshToken)

          /**
           * 当获取了最新的 refreshToken, accessToken 后
           * 重新发起之前失败的请求
           */
          retryRequest()
        }

        flag = false

        return res
      },
      responseFailureFn(err) {
        flag = false
        // console.log("张师易响应失败的拦截")
        return err
      }
    }
  })
}
